﻿using System;
using System.Collections.Generic;
using System.Linq;
using Ue.Eagle.Runtime;
using Ue.Eagle.Runtime.FileSystems.Dependencies;
using Ue.Eagle.Runtime.Models;

namespace Ue.Eagle.Runtime.Loaders
{
    /// <summary>
    /// 核心加载器
    /// 用于加载Ue.Eagle.Core中的插件
    /// </summary>
    public class CorePluginLoader : PluginLoaderBase
    {
        private const string CoreAssemblyName = "Ue.Eagle.Core";
        private readonly IAssemblyLoader assemblyLoader;

        public CorePluginLoader(IDependenciesFolder dependenciesFolder, IAssemblyLoader assemblyLoader)
            : base(dependenciesFolder)
        {
            this.assemblyLoader = assemblyLoader;
        }

        public bool Disabled { get; set; }

        public override int Priority { get { return 10; } }

        public override PluginProbeEntry Probe(PluginDescriptor descriptor)
        {
            if (Disabled)
                return null;

            if (descriptor.Location.StartsWith("/Core"))
            {
                return new PluginProbeEntry
                {
                    Descriptor = descriptor,
                    Loader = this,
                    Priority = 100, // 最高优先级，因为~/bin 目录总是最先考虑的。
                    VirtualPath = descriptor.Location,
                    VirtualPathDependencies = Enumerable.Empty<string>(),
                };
            }

            return null;
        }

        protected override Plugin LoadWorker(PluginDescriptor descriptor)
        {
            if (Disabled)
                return null;

            var assembly = this.assemblyLoader.Load(CoreAssemblyName);
            if (assembly == null)
            {
                return null;
            }

            return new Plugin
            {
                Descriptor = descriptor,
                Assembly = assembly,
                ExportedTypes = assembly.GetExportedTypes().Where(x => IsTypeFromModule(x, descriptor))
            };
        }

        private static bool IsTypeFromModule(Type type, PluginDescriptor descriptor)
        {
            return (type.Namespace + ".").StartsWith(descriptor.Id + ".");
        }
    }
}
